package com.axzhengxin.platform.afterloan.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.axzhengxin.platform.afterloan.domain.FspCorInf;
import com.axzhengxin.platform.afterloan.domain.RiskModelRegHistory;
import com.axzhengxin.platform.afterloan.mapper.RiskModelResultMapper;
import com.axzhengxin.platform.afterloan.service.IWarningTaskService;
import com.axzhengxin.platform.common.props.AuthFileSftpProps;
import com.axzhengxin.platform.common.service.IDbExecService;
import com.ruoyi.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * AbstractWarningTaskService
 *
 * @author jiangnan
 * @date 2021/4/2
 */
@Slf4j
public abstract class AbstractWarningTaskService implements IWarningTaskService {

    @Autowired
    private IDbExecService dbExecService;

    @Autowired
    private AuthFileSftpProps authFileSftpProps;

    @Autowired
    private RiskModelResultMapper riskModelResultMapper;

    @Value("${risk-model-url}")
    private String riskModelUrl;

    /**
     * 调用预警模型
     *
     * @param fspCorInfList 分页后的用户信息集合
     */
    protected void exec(List<FspCorInf> fspCorInfList) {
        try {
            fspCorInfList.stream()
                    .peek(this::fillLegalPersonIfBlank)
                    .map(RiskModelRequestData::new)
                    .peek(this::fillAuthFileContent)
                    .map(Collections::singletonList)
                    .map(RiskModelRequest::new)
                    .forEach(this::exec);
        } catch (Exception ex) {
            log.error("补全预警模型请求参数过程中发生异常", ex);
        }
    }

    /**
     * 调用预警模型
     *
     * @param request 预警模型请求报文对象
     */
    private void exec(RiskModelRequest request) {
        String response = StrUtil.EMPTY;
        try {
            String requestBody = JSON.toJSONString(request);
            response = HttpUtil.createPost(riskModelUrl)
                    .contentType(MediaType.APPLICATION_JSON_VALUE)
                    .body(requestBody)
                    .execute()
                    .body();
            log.info("预警模型返回报文:{}", response);
        } catch (Exception ex) {
            log.error("调用预警模型服务时发生异常", ex);
        }
        try {
            Optional.ofNullable(StrUtil.trimToNull(response))
                    .map(JSONUtil::parseObj)
                    .filter(jo -> jo.containsKey("code"))
                    .map(jo -> jo.getStr("code"))
                    .filter("200100"::equalsIgnoreCase)
                    .map(code -> RiskModelRegHistory.init(request))
                    .ifPresent(riskModelResultMapper::insertRegHistory);
        } catch (Exception ex) {
            log.error("写预警注册历史表发生异常", ex);
        }
    }

    /**
     * 对客户信息进行分页
     *
     * @param data 客户信息集合
     * @return 分页后的客户信息集合，每个元素都是一组客户信息
     */
    List<List<FspCorInf>> pageList(List<FspCorInf> data) {
        List<List<FspCorInf>> result = new ArrayList<>();
        boolean morePage;
        int pageNum = 0;
        do {
            List<FspCorInf> page = CollUtil.page(pageNum, PAGE_SIZE, data);
            morePage = CollUtil.isNotEmpty(page);
            pageNum = pageNum + 1;
            result.add(page);
        } while (morePage);
        return result.stream()
                .filter(CollUtil::isNotEmpty)
                .collect(Collectors.toList());
    }

    /**
     * 当客户法人名称为空时，从全国工商库补全
     *
     * @param fspCorInf 客户信息
     */
    private void fillLegalPersonIfBlank(FspCorInf fspCorInf) {
        if (StringUtils.isEmpty(fspCorInf.getLegalPerson())) {
            dbExecService.getLerpNameByEntName(fspCorInf.getName())
                    .ifPresent(fspCorInf::setLegalPerson);
        }
    }

    /**
     * 加载授权书内容
     *
     * @param data 预警模型请求报文体实体
     */
    private void fillAuthFileContent(RiskModelRequestData data) {
        fillAuthFileContent(data, authFileSftpProps);
    }

}
